﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using BSF.BaseService.MonitorPlatform.Model;

namespace BSF.Extensions
{
    /// <summary>
    /// 操作对象帮助类
    /// </summary>
    public static class OperationObjectHelper
    {

        public static Dictionary<string, string> GetDictFromXml(string xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            Dictionary<string, string> dict = new Dictionary<string, string>();
            foreach (XmlNode node in doc.DocumentElement.ChildNodes)
            {
                dict.Add(node.Name, node.InnerText.Trim());
            }
            return dict;
        }
        /// <summary>
        /// C#中属性PropertyInfo的使用,Dictionary转为Model实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dic"></param>
        /// <returns></returns>
        public static T ConvertDic<T>(Dictionary<string, object> dic)
        {
            T model = Activator.CreateInstance<T>();
            PropertyInfo[] modelPro = model.GetType().GetProperties();
            if (modelPro.Length > 0 && dic.Count() > 0)
            {
                for (int i = 0; i < modelPro.Length; i++)
                {
                    if (dic.ContainsKey(modelPro[i].Name))
                    {
                        modelPro[i].SetValue(model, dic[modelPro[i].Name], null);
                    }
                }
            }
            return model;
        }
        /// <summary>  
        /// Copy Propertys and Fileds   
        /// 拷贝属性和公共字段  
        /// </summary>  
        /// <typeparam name="T"> </typeparam>  
        /// <param name="source"></param>  
        /// <param name="target"></param>  
        public static void CopyToAll<T>(this object source, T target) where T : class
        {
            if (source == null)
            {
                return;
            }

            if (target == null)
            {
                throw new ApplicationException("target 未实例化！");
            }


            var properties = target.GetType().GetProperties();
            foreach (var targetPro in properties)
            {
                try
                {
                    //判断源对象是否存在与目标属性名字对应的源属性  
                    if (source.GetType().GetProperty(targetPro.Name) == null)
                    {
                        continue;
                    }
                    //数据类型不相等  
                    if (targetPro.PropertyType.FullName != source.GetType().GetProperty(targetPro.Name).PropertyType.FullName)
                    {
                        continue;
                    }
                    var propertyValue = source.GetType().GetProperty(targetPro.Name).GetValue(source, null);
                    if (propertyValue != null)
                    {

                        target.GetType().InvokeMember(targetPro.Name, BindingFlags.SetProperty, null, target, new object[] { propertyValue });
                    }
                }
                catch (Exception ex)
                {
                }
            }
            //返回所有公共字段  
            var targetFields = target.GetType().GetFields();
            foreach (var filed in targetFields)
            {
                try
                {
                    var tfield = source.GetType().GetField(filed.Name);
                    if (null == tfield)
                    {
                        //如果源对象中不包含这个公共字段则不处理  
                        continue;
                    }
                    //类型不一致不处理  
                    if (filed.FieldType.FullName != tfield.FieldType.FullName)
                    {
                        continue;
                    } var fieldValue = tfield.GetValue(source);
                    if (fieldValue != null)
                    {
                        target.GetType().InvokeMember(filed.Name, BindingFlags.SetField, null, target, new object[] { fieldValue });
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        /// <summary>  
        /// Copy Simple Property and Fileds  
        /// 拷贝简单属性和公共字段  
        /// </summary>  
        /// <typeparam name="T"></typeparam>  
        /// <param name="source"></param>  
        /// <param name="target"></param>  
        public static T CopyTo<T>(this object source, T target) where T : class
        {
            if (source == null)
            {
                return null;
            }

            if (target == null)
            {
                throw new ApplicationException("target 未实例化！");
            }

            var properties = target.GetType().GetProperties();
            foreach (var targetPro in properties)
            {
                try
                {
                    //判断源对象是否存在与目标属性名字对应的源属性  
                    if (source.GetType().GetProperty(targetPro.Name) == null)
                    {
                        continue;
                    }
                    //判断是否枚举集合  
                    if (targetPro.PropertyType.IsGenericType && targetPro.PropertyType.GetGenericArguments()[0].IsEnum)
                    {
                        continue;
                    }
                    // 判断是否数组  
                    else if (targetPro.PropertyType.IsArray)
                    {
                        continue;
                    }
                    // 判断是否IList  
                    else if (targetPro.PropertyType.IsGenericType && targetPro.PropertyType.GetInterface("System.Collections.IEnumerable") != null)
                    {
                        continue;
                    }

                    var propertyValue = source.GetType().GetProperty(targetPro.Name).GetValue(source, null);
                    if (propertyValue != null)
                    {
                        if (propertyValue.GetType().IsEnum)
                        {
                            continue;
                        }

                        target.GetType().InvokeMember(targetPro.Name, BindingFlags.SetProperty, null, target, new object[] { propertyValue });
                    }
                }
                catch (Exception ex)
                {

                }
            }

            //返回所有公共字段  
            var targetFields = target.GetType().GetFields();
            foreach (var filed in targetFields)
            {
                try
                {
                    var tfield = source.GetType().GetField(filed.Name);
                    if (null == tfield)
                    {
                        //如果源对象中不包含这个公共字段则不处理  
                        continue;
                    }
                    //类型不一致不处理  
                    if (filed.FieldType.FullName != tfield.FieldType.FullName)
                    {
                        continue;
                    }
                    var fieldValue = tfield.GetValue(source);
                    if (fieldValue != null)
                    {
                        target.GetType().InvokeMember(filed.Name, BindingFlags.SetField, null, target, new object[] { fieldValue });
                    }
                }
                catch (Exception ex)
                {
                }
            }
            return target;
        }
    }
}
